package com.scujj.cs6.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.scujj.cs6.mapper.CommentMapper;
import com.scujj.cs6.model.dto.comment.CommentDTO;
import com.scujj.cs6.model.dto.comment.CommentUpdateDTO;
import com.scujj.cs6.model.entity.Answer;
import com.scujj.cs6.model.entity.Comment;
import com.scujj.cs6.model.entity.Question;
import com.scujj.cs6.model.vo.CommentVo;
import com.scujj.cs6.model.vo.MyCommentVo;
import com.scujj.cs6.model.vo.PageVo;
import com.scujj.cs6.service.AnswerService;
import com.scujj.cs6.service.CommentService;
import com.scujj.cs6.service.QuestionService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
* @author FlanChan
* @description 针对表【comment】的数据库操作Service实现
* @createDate 2025-03-25 21:21:24
*/
@Service
@AllArgsConstructor
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment>
    implements CommentService{

    private final QuestionService questionService;

    private final AnswerService answerService;

    @Override
    public PageVo<MyCommentVo> pageMyComments(int page, int size , HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("user");
        List<MyCommentVo> commentVos = this.baseMapper.selectMyCommentsByUserId(userId, (page - 1) * size, size);
        int total = (int) this.count(new LambdaQueryWrapper<>(Comment.class).eq(Comment::getUserId, userId));
        PageVo<MyCommentVo> pageVo = new PageVo<>();
        pageVo.setRecords(commentVos);
        pageVo.setPage(page);
        pageVo.setSize(size);
        pageVo.setTotal(total);
        pageVo.setTotalPage((total + size - 1) / size);
        return pageVo;
    }

    @Override
    public PageVo<CommentVo> pageComments(Long id, int page, int size) {
        List<CommentVo> commentVos = this.baseMapper.selectCommentsWithUserByAnswerId(id, (page - 1) * size, size);
        int total = (int) this.count(new LambdaQueryWrapper<>(Comment.class).eq(Comment::getAnswerId, id));
        PageVo<CommentVo> pageVo = new PageVo<>();
        pageVo.setRecords(commentVos);
        pageVo.setPage(page);
        pageVo.setSize(size);
        pageVo.setTotal(total);
        pageVo.setTotalPage((total + size - 1) / size);
        return pageVo;
    }

    @Override
    public void createComment(CommentDTO commentDTO, HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("user");
        Long parentId = commentDTO.getParentId();
        if (parentId != null && parentId != -1) {
            Comment parentComment = this.getById(parentId);
            if (parentComment == null) {
                throw new RuntimeException("父评论不存在");
            }
        }
        if (questionService.count(new LambdaQueryWrapper<Question>().eq(Question::getId, commentDTO.getQuestionId())) == 0) {
            throw new RuntimeException("问题不存在");
        }
        if (answerService.count(new LambdaQueryWrapper<Answer>().eq(Answer::getId, commentDTO.getAnswerId())) == 0) {
            throw new RuntimeException("回答不存在");
        }
        Comment comment = new Comment(commentDTO);
        comment.setUserId(userId);
        this.save(comment);
    }

    @Override
    public void deleteComment(Long id, HttpServletRequest request) {
        Comment com = this.getById(id);
        if (com == null) {
            throw new RuntimeException("评论不存在");
        }
        if (!com.getUserId().equals(request.getAttribute("user"))) {
            throw new RuntimeException("无权限删除");
        }

        // 获取该评论及其所有子评论ID
        List<Long> allCommentIds = getAllChildCommentIds(id);
        allCommentIds.add(id); // 添加自身ID

        // 批量删除
        this.removeByIds(allCommentIds);
    }

    /**
     * 通过 BFS 获取所有子评论ID
     */
    private List<Long> getAllChildCommentIds(Long parentId) {
        List<Long> result = new ArrayList<>();
        Queue<Long> queue = new LinkedList<>();
        queue.add(parentId);

        while (!queue.isEmpty()) {
            Long currentParentId = queue.poll();

            // 查询当前父评论的直接子评论
            List<Long> childIds = this.list(new LambdaQueryWrapper<Comment>().eq(Comment::getParentId, currentParentId))
                    .stream()
                    .map(Comment::getId)
                    .toList();

            if (!childIds.isEmpty()) {
                result.addAll(childIds);
                queue.addAll(childIds); // 把子评论的 ID 加入队列，继续遍历
            }
        }

        return result;
    }


    @Override
    public void updateComment(Long id, CommentUpdateDTO commentDTO, HttpServletRequest request) {
        Comment com = this.getById(id);
        if (com == null) {
            throw new RuntimeException("评论不存在");
        }
        if (!com.getUserId().equals(request.getAttribute("user"))) {
            throw new RuntimeException("无权限修改");
        }
        com.setContent(commentDTO.getContent());
        this.updateById(com);
    }
}




